package org.sunspotworld;

import com.sun.spot.io.j2me.radiogram.*;
import com.sun.spot.util.IEEEAddress;
import com.sun.spot.util.Utils;
import com.sun.squawk.util.StringTokenizer;
import java.io.*;
import javax.microedition.io.*;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

/**
 *
 * @author Dani
 * @version 1.0
 */


public class Host implements Protocol {

    private Model model;
    private DatagramConnection broadcastConnection;

    public Host(Model model) {
        this.model = model;
    }

    /**
     * Command to send a "get score" broadcast message every second.
     */
    public void run() {
        try {
            broadcastConnection = (RadiogramConnection)
                    Connector.open("radiogram://broadcast:37");
        } catch (IOException ex) {}

        new MessageReceiveThread(this).start();

        new Thread(){
            public void run() {
                while(true) {
                    broadcast(GET_SCORE + "");
                    Utils.sleep(10000);
                }
            }
        }.start();

        while (true) {
            broadcast(GET_STATE + "");
            Utils.sleep(1000);
        }
    }

    /**
     * Command to broadcast the given String.
     * @param message Message that will be broadcasted
     */
    public void broadcast(String message) {
        try {
            Datagram datagram =
                    broadcastConnection.newDatagram(broadcastConnection.getMaximumLength());
            datagram.writeUTF(message);
            broadcastConnection.send(datagram);
        } catch (IOException ex) {}
    }

    /**
     * Start up the host application.
     * @param args any command line arguments
     */
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        } catch (InstantiationException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        } catch (UnsupportedLookAndFeelException ex) {
            ex.printStackTrace();
        }
        Model model = new Model();
        Host host = new Host(model);
        new View(model, host);
        host.run();
    }

    /**
     * Command to process the given Datagram. Either a new SunSPOT will be 
     * added to the model, or the given SunSPOT's score will be updated.
     * @param datagram the Datagram to be processed
     */
    public void receiveMessage(Datagram datagram) {
        long addressAsNumber = 0;

        try {
            String[] message = separateStrings(datagram.readUTF());
            addressAsNumber = IEEEAddress.toLong(datagram.getAddress());
            switch(Integer.parseInt(message[0])) {
                case RECEIVE_SCORE:
                    int score = Integer.parseInt(message[1]);
                    if (model.contains(addressAsNumber)) {
                        model.updateScore(addressAsNumber, score);
                    } else {
                        model.addSunSPOT(addressAsNumber, score);
                    }
                    break;
                case RECEIVE_STATE:
                    int state = Integer.parseInt(message[1]);
                    model.updateState(addressAsNumber, state);
                    break;
                case NOTPLAYING:
                    model.resetPlayTime();
                    break;
            }
        } catch(NumberFormatException ex) {
        } catch (IOException ex) {}
    }

    /**
     * Command to split a received String and put it in a Stirng array
     * @param message The String that needs to be split-up
     * @return String[] The split-up received String
     */
    public String[] separateStrings(String message) {
        StringTokenizer stk = new StringTokenizer(message, " ");
        String [] result = new String[stk.countTokens()];
        for (int i = 0; stk.hasMoreTokens(); i++) {
            result[i] = stk.nextToken();
        }
        return result;
    }
}
